package com.lintf.flowable.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lintf.common.exception.ServiceException;
import com.lintf.common.utils.string.StringUtils;
import com.lintf.flowable.domain.WorkOrder;
import com.lintf.flowable.dto.ProcessLaundryDTO;
import com.lintf.flowable.dto.WorkOrderDTO;
import com.lintf.flowable.model.EntityUtils;
import com.lintf.flowable.model.WorkOrderModel;
import com.lintf.flowable.service.WorkOrderService;
import com.lintf.flowable.mapper.WorkOrderMapper;
import com.lintf.flowable.token.user.UserContext;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.time.DateUtils.isSameDay;

/**
 * @author lintf
 * @description 针对表【t_work_order】的数据库操作Service实现
 * @createDate 2025-01-22 15:36:34
 */
@Service
public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder>
        implements WorkOrderService {

    @Override
    public List<WorkOrder> getWorkOrderList(WorkOrderDTO dto) {
        Map<String, Object> params = EntityUtils.entityToMap(dto);
        return baseMapper.selectWorkOrderList(params);
    }

    @Override
    public List<WorkOrderModel> getWorkOrderListByParams(WorkOrderDTO dto) {
        dto.setUserId(UserContext.getUser().getUserId());
        Map<String, Object> params = EntityUtils.entityToMap(dto);
        return baseMapper.selectWorkOrderListRefInfo(params);
    }

    @Override
    public Map<String, Object> getStatistics() {
        WorkOrderDTO dto = new WorkOrderDTO();
        dto.setUserId(UserContext.getUser().getUserId());
        Map<String, Object> params = EntityUtils.entityToMap(dto);
        List<WorkOrder> workOrders = baseMapper.selectWorkOrderList(params);
        List<WorkOrder> todayWorkOrders = workOrders.stream()
                .filter(workOrder -> workOrder.getCreateTime() != null && isSameDay(workOrder.getCreateTime(), new Date()))
                .collect(Collectors.toList());

        long totalCount = workOrders.size();
        long doingCount = workOrders.stream().filter(workOrder -> "进行中".equals(workOrder.getBusinessStatus())).count();
        long completeCount = workOrders.stream().filter(workOrder -> "待领取".equals(workOrder.getBusinessStatus())).count();
        long endCount = totalCount - doingCount - completeCount;
        long completeAndEndCount = completeCount + endCount;
        long completeTime = workOrders.stream().filter(workOrder -> workOrder.getCompleteTime() != null).mapToLong(WorkOrder::getCompleteTime).sum() / 1000 / 60;
        long meanTime = completeAndEndCount == 0 ? 0 : completeTime / completeAndEndCount;

        long todayTotalCount = todayWorkOrders.size();
        long todayDoingCount = todayWorkOrders.stream().filter(workOrder -> "进行中".equals(workOrder.getBusinessStatus())).count();
        long todayCompleteCount = todayWorkOrders.stream().filter(workOrder -> "待领取".equals(workOrder.getBusinessStatus())).count();
        long todayEndCount = todayTotalCount - todayDoingCount - todayCompleteCount;

        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", totalCount);
        statistics.put("doingCount", doingCount);
        statistics.put("completeCount", completeCount);
        statistics.put("endCount", endCount);
        statistics.put("completeAndEndCount", completeAndEndCount);
        statistics.put("completeTime", completeTime);
        statistics.put("meanTime", meanTime);
        statistics.put("todayTotalCount", todayTotalCount);
        statistics.put("todayDoingCount", todayDoingCount);
        statistics.put("todayCompleteCount", todayCompleteCount);
        statistics.put("todayEndCount", todayEndCount);
        return statistics;
    }

    @Override
    public void updateBusinessStatusByProcessInstanceId(String processInstanceId, String businessStatus, Long completeTime) {
        LambdaUpdateWrapper<WorkOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(WorkOrder::getProcessInstanceId, processInstanceId)
                .set(WorkOrder::getBusinessStatus, businessStatus)
                .set(WorkOrder::getUpdateTime, new Date());
        if (completeTime != null) {
            updateWrapper.set(WorkOrder::getCompleteTime, completeTime);
            updateWrapper.set(WorkOrder::getPosition, generateRandomPosition());
        }
        this.update(updateWrapper);
    }

    private String generateRandomPosition() {
        char randomChar = (char) ('A' + Math.random() * 26);
        int randomNumber = (int) (Math.random() * 100) + 1;
        return randomChar + String.valueOf(randomNumber);
    }

    @Override
    public void saveWorkOrder(ProcessLaundryDTO dto) {
        WorkOrder workOrder = new WorkOrder();
        workOrder.setProcessInstanceId(dto.getProcessInstanceId())
                .setUserId(dto.getUserId())
                .setStudentId(dto.getStudentId())
                .setBusinessStatus("进行中")
                .setCreateTime(new Date())
                .setCreateBy(String.valueOf(dto.getUserId()))
                .setUpdateTime(new Date())
                .setUpdateBy(String.valueOf(dto.getUserId()));
        this.save(workOrder);
    }

    @Override
    public WorkOrder getWorkOrderByOne(Integer userId, Integer studentId, String businessStatus) {
        LambdaQueryWrapper<WorkOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            queryWrapper.eq(WorkOrder::getUserId, userId);
        }
        if (studentId != null) {
            queryWrapper.eq(WorkOrder::getStudentId, studentId);
        }
        if (StringUtils.isNotEmpty(businessStatus)) {
            queryWrapper.eq(WorkOrder::getBusinessStatus, businessStatus);
        }
        return this.getOne(queryWrapper);
    }
}




